package io.renren.modules.app.service.impl;

import ch.qos.logback.classic.spi.ThrowableProxy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sun.org.apache.bcel.internal.generic.NEW;
import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.app.dao.BsBorrinformDao;
import io.renren.modules.app.dao.BsBorrviolationDao;
import io.renren.modules.app.entity.BsBookEntity;
import io.renren.modules.app.entity.BsBorrcertificateEntity;
import io.renren.modules.app.entity.BsBorrinformEntity;
import io.renren.modules.app.entity.BsBorrviolationEntity;
import io.renren.modules.app.service.BsBorrinformService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;



@Service("bsBorrinformService")
@Slf4j
@Transactional
public class BsBorrinformServiceImpl extends ServiceImpl<BsBorrinformDao, BsBorrinformEntity> implements BsBorrinformService {

    @Resource
    private BsBorrinformDao bsBorrinformDao ;

    @Resource
    private BsBorrviolationDao bsBorrviolationDao ;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        LambdaQueryWrapper<BsBorrinformEntity> queryWrapper = new LambdaQueryWrapper<>() ;
        if (params.get("bookname") != null && !params.get("bookname").equals("")){
            List<BsBookEntity> list = bsBorrinformDao.queryidByBookName(String.valueOf(params.get("bookname")));
            ArrayList<String> list1 = new ArrayList<>() ;
            if (list.size() > 0){
                for (BsBookEntity bsBook : list) {
                    list1.add(bsBook.getBooknum());
                }
                queryWrapper.in(BsBorrinformEntity::getInformbooknum,list1);
            }else {
                IPage<BsBorrinformEntity> page = this.page(
                        new Query<BsBorrinformEntity>().getPage(params),
                        new LambdaQueryWrapper<BsBorrinformEntity>().eq(BsBorrinformEntity::getId,-1)
                );
                return new PageUtils(page);
            }
        }
        if (params.get("certname") != null && !params.get("certname").equals("")){
            List<BsBorrcertificateEntity> list = bsBorrinformDao.queryidByCertName(String.valueOf(params.get("certname")));
            ArrayList<String> list1 = new ArrayList<>() ;
            if (list.size() > 0){
                for (BsBorrcertificateEntity entity : list) {
                    list1.add(entity.getCertnum());
                }
                queryWrapper.in(BsBorrinformEntity::getInformcertnum,list1);
            }else {
                IPage<BsBorrinformEntity> page = this.page(
                        new Query<BsBorrinformEntity>().getPage(params),
                        new LambdaQueryWrapper<BsBorrinformEntity>().eq(BsBorrinformEntity::getId,-1)
                );
                return new PageUtils(page);
            }
        }
        if (params.get("informdate") != null && !params.get("informdate").equals("")){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try {
                queryWrapper.eq(BsBorrinformEntity::getInformdate,sdf.parse(String.valueOf(params.get("informdate"))));
            } catch (ParseException e) {
                throw new RRException(e.getMessage());
            }
        }
        if (params.get("informreturndate") != null && !params.get("informreturndate").equals("")){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try {
                queryWrapper.eq(BsBorrinformEntity::getInformreturndate,sdf.parse(String.valueOf(params.get("informreturndate"))));
            } catch (ParseException e) {
                throw new RRException(e.getMessage());
            }
        }
        if (params.get("informrealdate") != null && !params.get("informrealdate").equals("")){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try {
                queryWrapper.eq(BsBorrinformEntity::getInformrealdate,sdf.parse(String.valueOf(params.get("informrealdate"))));
            } catch (ParseException e) {
                throw new RRException(e.getMessage());
            }
        }
        if (params.get("informstatus") != null && !params.get("informstatus").equals("")){
            queryWrapper.eq(BsBorrinformEntity::getInformstatus,params.get("informstatus"));
        }
        if (params.get("informid") != null && !params.get("informid").equals("")){
            queryWrapper.eq(BsBorrinformEntity::getId,params.get("informid"));
        }



        IPage<BsBorrinformEntity> page = this.page(
                new Query<BsBorrinformEntity>().getPage(params),
                queryWrapper
        );
        //图书名称，借阅者姓名数据清洗
        for (BsBorrinformEntity record : page.getRecords()) {
            //图书名称
            BsBookEntity bsBook = bsBorrinformDao.queryinformbooknum(record.getInformbooknum());
            record.setBookname(bsBook.getBookname());
            //借阅者名字
            BsBorrcertificateEntity entity = bsBorrinformDao.queryinformcertnum(record.getInformcertnum());
            record.setCertname(entity.getCertname());
        }

        return new PageUtils(page);
    }

    @Override
    public void saveBsBorrinformEntity(BsBorrinformEntity bsBorrinform) {
        try {
            //1：查询图书编号是否存在
            BsBookEntity bsBook = bsBorrinformDao.queryinformbooknum(bsBorrinform.getInformbooknum());
            if (bsBook == null){
                throw new RRException("请确认填写的图书编号");
            }
            //2：查询图书库存是否大于0
            if (bsBook.getBookstock() <= 0){
                throw new RRException("图书库存不足");
            }
            //3：查询借阅证编号是否存在
            BsBorrcertificateEntity entity = bsBorrinformDao.queryinformcertnum(bsBorrinform.getInformcertnum());
            if (entity == null){
                throw new RRException("请确认填写的借阅证编号");
            }
            //4：判断借阅证编号是否已启用
            if ("未启用".equals(entity.getCertstatus())){
                throw new RRException("此借阅证号未启用，请先启用再操作");
            }
            Date informdate = bsBorrinform.getInformdate();//借阅日期
            Date informreturndate = bsBorrinform.getInformreturndate();//应归还日期
            //5：借阅日期应小于等于应归还日期
            if (informdate.getTime() > informreturndate.getTime()){
                throw new RRException("借阅日期应小于等于应归还日期");
            }
            //6: 新增操作时，实际归还日期不允许填写，并且借阅状态只能为未归还
            Date informrealdate = bsBorrinform.getInformrealdate();//实际归还日期
            if (informrealdate != null){
                throw new RRException("新增操作时，实际归还日期不允许填写");
            }
            if ("已归还".equals(bsBorrinform.getInformstatus())){
                throw new RRException("新增操作时，借阅状态只能为未归还");
            }
            //7: 图书库存-1
            Integer bookstock = bsBook.getBookstock() - 1;//图书库存-1
            String informbooknum = bsBorrinform.getInformbooknum();//图书编号
            int i1 = bsBorrinformDao.updateBook(informbooknum,bookstock);
            if (i1 != 1){
                throw new RRException("新增失败");
            }
            //执行新增操作
            bsBorrinformDao.insert(bsBorrinform);
        }catch (Exception e){
            log.info(e.getMessage());
            throw new RRException(e.getMessage());
        }
    }

    @Override
    public void updateBsBorrinformEntity(BsBorrinformEntity bsBorrinform) {
        try {
            Integer id = bsBorrinform.getId();
            BsBorrinformEntity bsBorrinformEntity = bsBorrinformDao.selectById(id);
            //1: 图书编号，借阅证编号，借阅日期，应归还日期均不允许修改
            if (!bsBorrinform.getInformbooknum().equals(bsBorrinformEntity.getInformbooknum())){
                throw new RRException("图书编号不允许修改");
            }
            if (!bsBorrinform.getInformcertnum().equals(bsBorrinformEntity.getInformcertnum())){
                throw new RRException("借阅证编号不允许修改");
            }
            if (bsBorrinform.getInformdate().getTime() != bsBorrinformEntity.getInformdate().getTime()){
                throw new RRException("借阅日期不允许修改");
            }
            if (bsBorrinform.getInformreturndate().getTime() != bsBorrinformEntity.getInformreturndate().getTime()){
                throw new RRException("应归还日期不允许修改");
            }
            //如果当前图书已经归还完毕，那么不允许进行任何修改
            if (bsBorrinformEntity.getInformreturndate() != null && "已归还".equals(bsBorrinformEntity.getInformstatus())){
                throw new RRException("已经归还的图书不允许进行修改信息");
            }
            //2：实际归还日期与归还状态校验
            if (bsBorrinform.getInformrealdate() != null){
                if ("未归还".equals(bsBorrinform.getInformstatus())){
                    throw new RRException("请确认归还状态");
                }
            }
            if (bsBorrinform.getInformrealdate() == null){
                if ("已归还".equals(bsBorrinform.getInformstatus())){
                    throw new RRException("请确认归还状态");
                }
            }
            //3：若实际归还日期不为空，需要确保实际归还日期大于等于借阅日期
            if (bsBorrinform.getInformrealdate() != null){
                if (bsBorrinform.getInformrealdate().getTime() < bsBorrinform.getInformdate().getTime()){
                    throw new RRException("借阅日期应小于等于归还日期");
                }
                //图书库存+ 1
                BsBookEntity bsBook = bsBorrinformDao.queryinformbooknum(bsBorrinform.getInformbooknum());
                Integer bookstock = bsBook.getBookstock() + 1;//图书库存 + 1
                String informbooknum = bsBorrinform.getInformbooknum();//图书编号
                int i1 = bsBorrinformDao.updateBook(informbooknum,bookstock);
                if (i1 != 1){
                    throw new RRException("新增失败");
                }
            }
            //4：应归还日期与实际归还日期校验
            //若实际归还日期大于应归还日期，说明该读者逾期还书，需要补缴罚款 并对违约信息表新增一条数据
            if (bsBorrinform.getInformrealdate() != null){
                if (bsBorrinform.getInformrealdate().getTime() > bsBorrinform.getInformreturndate().getTime()){
                    Integer id1 = bsBorrinform.getId(); //借阅信息ID
                    BsBorrviolationEntity bsBorrviolationEntity = new BsBorrviolationEntity();
                    bsBorrviolationEntity.setCreateTime(new Date());
                    bsBorrviolationEntity.setUpdateTime(new Date());
                    bsBorrviolationEntity.setViolainformid(id1);
                    bsBorrviolationEntity.setVioladescribe("违约");
                    bsBorrviolationEntity.setViolainprice(new Double(0.00));
                    bsBorrviolationDao.insert(bsBorrviolationEntity);
                }
            }
            //执行修改动作
            bsBorrinformDao.updateById(bsBorrinform) ;
        }catch (Exception e){
            log.info(e.getMessage());
            throw new RRException(e.getMessage());
        }
    }

}
